package utils.parser;

import java.io.EOFException;
import java.io.IOException;
import java.io.StringReader;
import utils.parser.IntegerRingBuffer;

/**
 * Provides look-ahead capability to aid in tokenizer implementations.
 * 
 * @author
 */
public abstract class BaseTokenizer {
	private StringReader in;
	private IntegerRingBuffer buf = new IntegerRingBuffer();

	public BaseTokenizer(StringReader in) {
		this.in = in;
	}

	public abstract boolean hasNextToken() throws IOException;

	public abstract String nextToken() throws IOException;

	// pop up the specified element from the buffer
	protected void consume(char c) throws IOException {
		int ci = peekNoEOF(0);
		if (c == ci) {
			buf.pop();
		} else {
			throw new Error("Value mismatch in Tokenizer.consume()");
		}
	}

	// get the specified element from the buffer
	protected char peek(int n) throws IOException {
		int rc = peekNoEOF(n);
		if (rc == -1) {
			throw new EOFException();
		}
		return (char) rc;
	}

	// read from buffer or from the input source
	protected int peekNoEOF(int n) throws IOException {
		while (n >= buf.size()) {
			int ci = in.read();
			if (ci == -1) {
				return -1;
			}
			buf.push(ci);
		}
		return (char) buf.get(n);
	}
}
